/*
 * =====================================================================================
 *
 *       Filename:  log.h
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2014年07月25日 10时13分27秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  jianxi sun (jianxi), ycsunjane@gmail.com
 *   Organization:  
 *
 * =====================================================================================
 */
#ifndef __LOG_H__
#define __LOG_H__
#include <syslog.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>

#include "config.h"

extern int debug;
extern int daemon_enable;

//#define	LOG_EMERG	0	/* system is unusable */
//#define	LOG_ALERT	1	/* action must be taken immediately */
//#define	LOG_CRIT	2	/* critical conditions */
//#define	LOG_ERR		3	/* error conditions */
//#define	LOG_WARNING	4	/* warning conditions */
//#define	LOG_NOTICE	5	/* normal but significant condition */
//#define	LOG_INFO	6	/* informational */
//#define	LOG_DEBUG	7	/* debug-level messages */

#define __R_FILE__  ((strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__))

#define __sys_log(LEVEL, fmt, ...) 	\
	do { 				\
		if(LEVEL <= debug) { 	\
			if(daemon_enable) { 	\
				syslog(LEVEL|LOG_USER, "%s +%u %s(): "fmt, 	\
					__R_FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
			} else { 							\
				fprintf(stderr, "%s +%u %s(): "fmt, 		\
					__R_FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
			} 	\
		} 		\
	} while(0)


#ifdef DEBUG
#define sys_err(fmt, ...) 	__sys_log(LOG_ERR, "ERR: "fmt, ##__VA_ARGS__)
#define sys_warn(fmt, ...) 	__sys_log(LOG_WARNING, "WARNING: "fmt, ##__VA_ARGS__)
#define sys_info(fmt, ...) 	__sys_log(LOG_INFO, "INFO: "fmt, ##__VA_ARGS__)
#define sys_debug(fmt, ...) 	__sys_log(LOG_DEBUG, "DEBUG: "fmt, ##__VA_ARGS__)
#define sys_lock(fmt, ...) 	__sys_log(LOG_DEBUG, "LOCK: "fmt, ##__VA_ARGS__)
#else
#define sys_err(fmt, ...)  	NULL
#define sys_warn(fmt, ...) 	NULL
#define sys_info(fmt, ...) 	NULL
#define sys_debug(fmt, ...) 	NULL
#define sys_lock(fmt, ...) 	NULL
#endif

#define __sys_log2(LEVEL, fmt, ...) 	\
	do { 				\
		if(LEVEL <= debug) { 	\
			if(daemon_enable) { 	\
				syslog(LEVEL|LOG_USER, fmt, 	\
					##__VA_ARGS__); \
			} else { 		\
				fprintf(stderr, fmt, 		\
					##__VA_ARGS__); \
			} 	\
		} 		\
	} while(0)



#ifdef DEBUG
static 	char _macstr[18] = {0};
static char *_cmac(uint64_t lmac)
{
	unsigned char *mac = (unsigned char *)&lmac;
	sprintf(_macstr, "%02x:%02x:%02x:%02x:%02x:%02x",
		mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
	return &_macstr[0];
}

#define pure_info(fmt, ...) 	__sys_log2(LOG_DEBUG, fmt, ##__VA_ARGS__)
#define pure_info2(fmt, ...) 	__sys_log2(LOG_ERR, fmt, ##__VA_ARGS__)
#define MAC(mac) _cmac(mac)
#define mac_debug(mac, fmt, ...)        __sys_log(LOG_DEBUG, "%s "fmt, mac, ##__VA_ARGS__)
#else
#define pure_info(fmt, ...) 	NULL
#define pure_info2(fmt, ...) 	NULL
#define MAC(mac) NULL
#define mac_debug(mac, fmt, ...)        NULL
#endif

#define pr_mac(mac) 							\
do { 									\
	char *_mac = (void *)(mac); 					\
	sys_debug("%02x:%02x:%02x:%02x:%02x:%02x\n", 			\
		(unsigned char) (_mac)[0], 				\
		(unsigned char) (_mac)[1], 				\
		(unsigned char) (_mac)[2], 				\
		(unsigned char) (_mac)[3], 				\
		(unsigned char) (_mac)[4], 				\
		(unsigned char) (_mac)[5]); 				\
} while(0)

#define panic() 		\
do { 				\
	sys_err("Panic\n"); 	\
	exit(-1); 		\
} while(0)


#ifdef PRPKT
static void pr_pkt(char *hit, void *arg, ssize_t len)
{
	uint8_t *pkt = arg;
	if(!debug) return;
	int i;
	pure_info("%s\n", hit);
	for(i = 0; i < len; i++) {
		pure_info("%02x ", pkt[i]);
		if((i+1) % 8 == 0)
			pure_info("   ");
		if((i+1) % 16 == 0)
			pure_info("\n");
	}
	pure_info("\n");
}
static void pr_pkt2(char *hit, void *arg, ssize_t len)
{
	uint8_t *pkt = arg;
	if(!debug) return;
	int i;
	pure_info2("%s\n", hit);
	for(i = 0; i < len; i++) {
		pure_info2("%02x ", pkt[i]);
		if((i+1) % 8 == 0)
			pure_info2("   ");
		if((i+1) % 16 == 0)
			pure_info2("\n");
	}
	pure_info2("\n");
}
#else
#define pr_pkt(hit,pkt,len) NULL
#define pr_pkt2(hit,pkt,len) NULL
#endif

#endif /* __LOG_H__ */
